const Fmt = {
	Bin1: 0,
	Bin2: 1,
	Bin4: 2,
	Da: 3,
	Dt: 4,
	Bcd2: 12,
	Bcd6: 16,
	Data1: 100,
}

function XBuffer(arr) {
	this.pos = 0;
	this.bytes = new Uint8Array(arr);
}

XBuffer.prototype.isEE = function(pos, len) {
	for (let i = 0; i < len; i++) {
		if (this.bytes[pos + i] != 0xEE) return false;
	}
	return true;
}
//按格式取数据，如果指定p 则不移动指针this.pos
XBuffer.prototype.get = function(f, p) {
	let pos = this.pos;
	if (p) pos = p;
	let vlen = 1;
	var val;
	switch (f) {
		case Fmt.Data1:
			vlen = 6;
			if (this.isEE(pos, 6)) {
				val = new DateUtil("2000-01-01").toStr();
			} else {
				//String[] weekStr = new String[]{"无效星期", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
				let ss = this.getBcdStr(pos++, 1);
				let nn = this.getBcdStr(pos++, 1);
				let hh = this.getBcdStr(pos++, 1);
				let dd = this.getBcdStr(pos++, 1);
				let wwmm = this.bytes[pos++];
				let mm = Util.byteToStr(wwmm & 0x1F);
				let ww = (wwmm & 0xE0) >> 5;
				let yy = this.getBcdStr(pos++, 1);
				let dtStr = "20{0}-{1}-{2} {3}:{4}:{5}".format(yy, mm, dd, hh, nn, ss);
				return dtStr;
			}
			break;
		case Fmt.Dt:
			vlen = 2;
			let dt1 = this.bytes[pos];
			val = this.bytes[pos + 1] * 8;
			let c = 0;
			while (dt1 > 0) {
				c++;
				dt1 = dt1 >> 1;
			}
			val += c;
			break;
		case Fmt.Da:
			vlen = 2;
			let da1 = this.bytes[pos];
			let da2 = this.bytes[pos + 1];
			if ((da1 == 0 && da2 == 0) || (da1 == 0xFF && da2 == 0xFF)) {
				val = 0;
			} else {
				val = (da2 - 1) * 8;
				let c = 0;
				while (da1 > 0) {
					c++;
					da1 = da1 >> 1;
				}
				val += c;
			}
			break;
		case Fmt.Bcd2:
			vlen = 2;
			val = this.getBcdStr(pos, 2);
			break;
		case Fmt.Bcd6:
			vlen = 6;
			val = this.getBcdStr(pos, 6);
			break;
		case Fmt.Bin2:
		case Fmt.Bin4:
			let len = 2;
			if (f == Fmt.Bin4) len = 4;
			val = 0;
			for (let i = 0; i < len; i++) {
				val += this.bytes[pos + i] << i;
			}
			vlen = len;
			break;
		case Fmt.Bin1:
			val = this.bytes[pos];
			break;
		default:
			throw Error("格式" + f + "错误");
			break;
	}
	if (!p) this.pos += vlen;
	return val;
}
XBuffer.prototype.getBcdStr = function(p, len, sep) {
	let ret = "";
	let separator = "";
	if (sep) separator = sep;
	for (let i = 0; i < len; i++) {
		ret = Util.byteToStr(this.bytes[p + i]) + ret;
		if (!sep) continue;
		if (i < len - 1) ret = separator + ret;
	}
	return ret;
}
XBuffer.prototype.set = function(val, f, p) {
	let pos = this.pos;
	if (p) pos = p;
	let vlen = 1;
	switch (f) {

		case Fmt.Da:
			let da = val,
				da1 = 1,
				da2 = 1;
			if (val == 0) {
				da1 = da2 = 0;
			} else {
				while (da2 < 255) {
					let max = (da2) * 8;
					if (max >= da) {
						da1 = da1 << (7 - (max - da));
						break;
					}
					da2++;
				}
			}
			this.bytes[pos + 0] = da1;
			this.bytes[pos + 1] = da2;
			vlen = 2;
			break;
		case Fmt.Dt:
			let dt = val,
				dt1 = 1,
				dt2 = 0;
			while (dt2 < 255) {
				let max = (dt2 + 1) * 8;
				if (max >= dt) {
					dt1 = dt1 << (7 - (max - dt));
					break;
				}
				dt2++;
			}
			this.bytes[pos + 0] = dt1;
			this.bytes[pos + 1] = dt2;
			vlen = 2;
			break;
		case Fmt.Bin2:
		case Fmt.Bin4:
			let len = 2;
			if (f == Fmt.Bin4) len = 4;
			for (let i = 0; i < len; i++) {
				this.bytes[pos + i] = Util.byteOfLong(val, i);
			}
			vlen = len;
			break;
		case Fmt.Bin1:
		default:
			this.bytes[pos] = val;
			break;
	}
	if (!p) this.pos += vlen;
}
